home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 8: LINUX Games
/
Linux Cubed Series 8 - LINUX Games.iso
/
games
/
x11
/
strategy
/
xpuzzles.3
/
xpuzzles
/
xpuzzles-5.3.1
/
xdino
/
xdino.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-04-02
|
13KB
|
448 lines
/*
# X-BASED DINOSAUR CUBE
#
# xdino.c
#
###
#
# Copyright (c) 1995 - 96 David Albert Bagley, bagleyd@hertz.njit.edu
#
# All Rights Reserved
#
# Permission to use, copy, modify, and distribute this software and
# its documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and
# that both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of the author not be
# used in advertising or publicity pertaining to distribution of the
# software without specific, written prior permission.
#
# This program is distributed in the hope that it will be "playable",
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
*/
/*
Version 4: 94/05/30 Xt
*/
#include <stdlib.h>
#include <stdio.h>
#ifdef VMS
#include <unixlib.h>
#define getlogin cuserid
#else
#ifndef apollo
#include <unistd.h>
#endif
#endif
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#include <X11/cursorfont.h>
#include "Dino.h"
#include "Dino2d.h"
#include "Dino3d.h"
#include "dino.xbm"
#ifndef SCOREFILE
#define SCOREFILE "/usr/games/lib/dino.scores"
#endif
/* The following are in DinoP.h also */
#define PERIOD2 2
#define PERIOD3 3
#define BOTH 4
#define MAXMODES 3
#define MAXFACES 6
#define MAXRECORD 32767
#define MAXPROGNAME 80
#define MAXNAME 256
static void Initialize();
static void CallbackDino();
static void PrintRecord();
static int HandleSolved();
static void PrintState();
static void ReadRecords();
static void WriteRecords();
static Widget dino2d, dino3d;
static Arg arg[5];
static int dinoRecord[MAXMODES][2], movesDsp = 0;
static char progDsp[64] = "xdino";
static char recordDsp[16] = "INF";
static char messageDsp[128] = "Welcome";
static char titleDsp[256] = "";
static void Usage()
{
(void) fprintf(stderr, "usage: xdino\n");
(void) fprintf(stderr,
"\t[-geometry [{width}][x{height}][{+-}{xoff}[{+-}{yoff}]]]\n");
(void) fprintf(stderr,
"\t[-display [{host}]:[{vs}]][-fg {color}] [-bg {color}]\n");
(void) fprintf(stderr,
"\t[-{border|bd} {color}] [-mono] [-{mode {int} | both}] [-[no]orient]\n");
(void) fprintf(stderr,
"\t[-[no]practice] [-face{0|1|2|3|4|5} {color}]\n");
exit(1);
}
static XrmOptionDescRec options[] = {
{"-fg", "*dino.Foreground", XrmoptionSepArg, NULL},
{"-bg", "*Background", XrmoptionSepArg, NULL},
{"-foreground", "*dino.Foreground", XrmoptionSepArg, NULL},
{"-background", "*Background", XrmoptionSepArg, NULL},
{"-border", "*dino.pieceBorder", XrmoptionSepArg, NULL},
{"-bd", "*dino.pieceBorder", XrmoptionSepArg, NULL},
{"-mono", "*dino.mono", XrmoptionNoArg, "TRUE"},
{"-mode", "*dino.mode", XrmoptionSepArg, NULL},
{"-both", "*dino.mode", XrmoptionNoArg, "4"},
{"-orient", "*dino.orient", XrmoptionNoArg, "TRUE"},
{"-noorient", "*dino.orient", XrmoptionNoArg, "FALSE"},
{"-practice", "*dino.practice", XrmoptionNoArg, "TRUE"},
{"-nopractice", "*dino.practice", XrmoptionNoArg, "FALSE"},
{"-face0", "*dino.faceColor0", XrmoptionSepArg, NULL},
{"-face1", "*dino.faceColor1", XrmoptionSepArg, NULL},
{"-face2", "*dino.faceColor2", XrmoptionSepArg, NULL},
{"-face3", "*dino.faceColor3", XrmoptionSepArg, NULL},
{"-face4", "*dino.faceColor4", XrmoptionSepArg, NULL},
{"-face5", "*dino.faceColor5", XrmoptionSepArg, NULL},
};
int main(argc, argv)
int argc;
char *argv[];
{
Widget toplevel, shell;
toplevel = XtInitialize(argv[0], "Dino",
options, XtNumber(options), &argc, argv);
if (argc != 1)
Usage();
shell = XtCreateApplicationShell(argv[0], topLevelShellWidgetClass, NULL,
0);
XtSetArg(arg[0], XtNiconPixmap,
XCreateBitmapFromData(XtDisplay(toplevel),
RootWindowOfScreen(XtScreen(toplevel)),
(char *) dino_bits, dino_width, dino_height));
XtSetValues(toplevel, arg, 1);
XtSetArg(arg[0], XtNiconPixmap,
XCreateBitmapFromData(XtDisplay(shell),
RootWindowOfScreen(XtScreen(shell)),
(char *) dino_bits, dino_width, dino_height));
XtSetValues(shell, arg, 1);
dino2d = XtCreateManagedWidget("dino", dino2dWidgetClass, toplevel,
NULL, 0);
XtAddCallback(dino2d, XtNselectCallback, CallbackDino, NULL);
dino3d = XtCreateManagedWidget("dino", dino3dWidgetClass, shell,
NULL, 0);
XtAddCallback(dino3d, XtNselectCallback, CallbackDino, NULL);
Initialize();
XtRealizeWidget(toplevel);
XtRealizeWidget(shell);
XGrabButton(XtDisplay(dino2d), AnyButton, AnyModifier, XtWindow(dino2d),
TRUE, ButtonPressMask | ButtonMotionMask | ButtonReleaseMask,
GrabModeAsync, GrabModeAsync, XtWindow(dino2d),
XCreateFontCursor(XtDisplay(dino2d), XC_crosshair));
XGrabButton(XtDisplay(dino3d), AnyButton, AnyModifier, XtWindow(dino3d),
TRUE, ButtonPressMask | ButtonMotionMask | ButtonReleaseMask,
GrabModeAsync, GrabModeAsync, XtWindow(dino3d),
XCreateFontCursor(XtDisplay(dino3d), XC_crosshair));
XtMainLoop();
#ifdef VMS
return 1;
#else
return 0;
#endif
}
/* There's probably a better way to assure that they are the same but
I don't know it off hand. */
static void MakeEquivalent(mode, orient, practice)
int *mode;
Boolean *orient, *practice;
{
Boolean mono;
Pixel foreground, background, pieceBorder;
String faceColor[MAXFACES];
XtVaGetValues(dino2d,
XtNmode, mode,
XtNorient, orient,
XtNpractice, practice,
XtNmono, &mono,
XtNforeground, &foreground,
XtNbackground, &background,
XtNpieceBorder, &pieceBorder,
XtNfaceColor0, &(faceColor[0]),
XtNfaceColor1, &(faceColor[1]),
XtNfaceColor2, &(faceColor[2]),
XtNfaceColor3, &(faceColor[3]),
XtNfaceColor4, &(faceColor[4]),
XtNfaceColor5, &(faceColor[5]),
NULL);
XtVaSetValues(dino2d,
XtNdirection, DINO_IGNORE,
XtNstart, FALSE,
NULL);
XtVaSetValues(dino3d,
XtNmode, *mode,
XtNorient, *orient,
XtNpractice, *practice,
XtNmono, mono,
XtNdirection, DINO_IGNORE,
XtNstart, FALSE,
XtNforeground, foreground,
XtNbackground, background,
XtNpieceBorder, pieceBorder,
XtNfaceColor0, faceColor[0],
XtNfaceColor1, faceColor[1],
XtNfaceColor2, faceColor[2],
XtNfaceColor3, faceColor[3],
XtNfaceColor4, faceColor[4],
XtNfaceColor5, faceColor[5],
NULL);
}
static void Initialize()
{
int mode;
Boolean orient, practice;
MakeEquivalent(&mode, &orient, &practice);
ReadRecords();
PrintRecord(mode, orient, practice, recordDsp);
PrintState(XtParent(dino2d), progDsp, 2, mode, movesDsp,
recordDsp, messageDsp);
PrintState(XtParent(dino3d), progDsp, 3, mode, movesDsp,
recordDsp, messageDsp);
}
static void CallbackDino(w, clientData, callData)
Widget w;
caddr_t clientData;
dinoCallbackStruct *callData;
{
int mode, dim, otherdim;
Boolean orient, practice, start;
Widget otherw;
if (w == dino2d) {
dim = 2;
otherw = dino3d;
otherdim = 3;
} else { /* (w == dino3d) */
dim = 3;
otherw = dino2d;
otherdim = 2;
}
XtVaGetValues(w,
XtNorient, &orient,
XtNmode, &mode,
XtNpractice, &practice,
XtNstart, &start,
NULL);
(void) strcpy(messageDsp, "");
switch (callData->reason) {
case DINO_RESTORE:
XtSetArg(arg[0], XtNdirection, DINO_RESTORE);
XtSetValues(otherw, arg, 1);
XtSetValues(w, arg, 1);
movesDsp = 0;
break;
case DINO_RESET:
movesDsp = 0;
break;
case DINO_ILLEGAL:
if (practice || start)
(void) strcpy(messageDsp, "Illegal move");
else
(void) strcpy(messageDsp, "Randomize to start");
break;
case DINO_MOVED:
movesDsp++;
#ifdef DEBUG
if (movesDsp > 256)
exit(1);
#endif
XtSetArg(arg[0], XtNstart, TRUE);
XtSetArg(arg[1], XtNface, callData->face);
XtSetArg(arg[2], XtNpos, callData->position);
XtSetArg(arg[3], XtNdirection, callData->direction);
XtSetArg(arg[4], XtNstyle, callData->style);
XtSetValues(otherw, arg, 5);
XtSetValues(w, arg, 1);
break;
case DINO_CONTROL:
XtSetArg(arg[0], XtNface, callData->face);
XtSetArg(arg[1], XtNpos, callData->position);
XtSetArg(arg[2], XtNdirection, callData->direction);
XtSetArg(arg[3], XtNstyle, callData->style);
XtSetValues(otherw, arg, 4);
return;
case DINO_SOLVED:
if (practice)
movesDsp = 0;
else {
if (HandleSolved(movesDsp, mode, orient))
(void) sprintf(messageDsp, "Congratulations %s!!", getlogin());
else
(void) strcpy(messageDsp, "Solved!");
}
XtSetArg(arg[0], XtNstart, FALSE);
XtSetValues(w, arg, 1);
XtSetValues(otherw, arg, 1);
break;
case DINO_PRACTICE:
movesDsp = 0;
practice = !practice;
if (!practice)
(void) strcpy(messageDsp, "Randomize to start");
PrintRecord(mode, orient, practice, recordDsp);
XtSetArg(arg[0], XtNpractice, practice);
XtSetArg(arg[1], XtNstart, FALSE);
XtSetValues(w, arg, 2);
XtSetValues(otherw, arg, 2);
break;
case DINO_RANDOMIZE:
movesDsp = 0;
XtSetArg(arg[0], XtNpractice, FALSE);
XtSetArg(arg[1], XtNstart, FALSE);
XtSetValues(w, arg, 2);
XtSetValues(otherw, arg, 2);
break;
case DINO_ORIENT:
movesDsp = 0;
orient = !orient;
PrintRecord(mode, orient, practice, recordDsp);
XtSetArg(arg[0], XtNorient, orient);
XtSetValues(w, arg, 1);
XtSetValues(otherw, arg, 1);
break;
case DINO_PERIOD2:
case DINO_PERIOD3:
case DINO_BOTH:
movesDsp = 0;
mode = callData->reason - DINO_PERIOD2 + PERIOD2;
PrintRecord(mode, orient, practice, recordDsp);
XtSetArg(arg[0], XtNmode, mode);
XtSetValues(w, arg, 1);
XtSetValues(otherw, arg, 1);
break;
case DINO_COMPUTED:
XtSetArg(arg[0], XtNstart, FALSE);
XtSetValues(w, arg, 1);
XtSetValues(otherw, arg, 1);
break;
case DINO_UNDO:
movesDsp--;
XtSetArg(arg[0], XtNstart, TRUE);
XtSetArg(arg[1], XtNface, callData->face);
XtSetArg(arg[2], XtNpos, callData->position);
XtSetArg(arg[3], XtNdirection, callData->direction);
XtSetArg(arg[4], XtNstyle, callData->style);
XtSetValues(otherw, arg, 5);
XtSetValues(w, arg, 1);
break;
}
PrintState(XtParent(w), progDsp, dim, mode, movesDsp,
recordDsp, messageDsp);
PrintState(XtParent(otherw), progDsp, otherdim, mode, movesDsp,
recordDsp, messageDsp);
}
static void PrintRecord(mode, orient, practice, record)
int mode;
Boolean orient, practice;
char *record;
{
int i = mode - PERIOD2;
int j = (orient) ? 1 : 0;
if (practice)
(void) strcpy(record, "practice");
else if (dinoRecord[i][j] >= MAXRECORD)
(void) strcpy(record, "NEVER");
else
(void) sprintf(record, "%d", dinoRecord[i][j]);
}
static int HandleSolved(counter, mode, orient)
int counter, mode;
Boolean orient;
{
int i = mode - PERIOD2;
int j = (orient) ? 1 : 0;
if (counter < dinoRecord[i][j]) {
dinoRecord[i][j] = counter;
if (orient && (dinoRecord[i][j] < dinoRecord[!i][j]))
dinoRecord[!i][j] = counter;
WriteRecords();
(void) sprintf(recordDsp, "%d", counter);
return TRUE;
}
return FALSE;
}
static void PrintState(w, prog, dim, mode, moves, record, message)
Widget w;
char *prog, *record, *message;
int mode, dim, moves;
{
char mb[10];
if (mode == BOTH)
(void) strcpy(mb, "both");
else
(void) sprintf(mb, "%d", mode);
(void) sprintf(titleDsp, "%s%dd.%s: (%d/%s) - %s", prog, dim, mb, moves,
record, message);
XtSetArg(arg[0], XtNtitle, titleDsp);
XtSetValues(w, arg, 1);
}
static void ReadRecords()
{
FILE *fp;
int n, mode, orient;
for (mode = 0; mode < MAXMODES; mode++)
for (orient = 0; orient < 2; orient++)
dinoRecord[mode][orient] = MAXRECORD;
if ((fp = fopen(SCOREFILE, "r")) == NULL)
(void) sprintf(messageDsp, "Can not open %s, taking defaults.", SCOREFILE);
else {
for (mode = 0; mode < MAXMODES; mode++)
for (orient = 0; orient < 2; orient++) {
(void) fscanf(fp, "%d", &n);
dinoRecord[mode][orient] = n;
}
(void) fclose(fp);
}
}
static void WriteRecords()
{
FILE *fp;
int mode, orient;
if ((fp = fopen(SCOREFILE, "w")) == NULL)
(void) sprintf(messageDsp, "Can not write to %s.", SCOREFILE);
else {
for (mode = 0; mode < MAXMODES; mode++) {
for (orient = 0; orient < 2; orient++)
(void) fprintf(fp, "%d ", dinoRecord[mode][orient]);
(void) fprintf(fp, "\n");
}
(void) fclose(fp);
}
}